home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / GAS_1_38.ARJ / SPARC.C < prev    next >
C/C++ Source or Header  |  1990-10-22  |  27KB  |  1,286 lines

  1. /* sparc.c -- Assemble for the SPARC
  2.    Copyright (C) 1989 Free Software Foundation, Inc.
  3.  
  4. This file is part of GAS, the GNU Assembler.
  5.  
  6. GAS is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 1, or (at your option)
  9. any later version.
  10.  
  11. GAS is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with GAS; see the file COPYING.  If not, write to
  18. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20.  
  21. #include <stdio.h>
  22. #include <ctype.h>
  23.  
  24. #include "sparc-opcode.h"
  25. #include "as.h"
  26. #include "frags.h"
  27. #include "struc-symbol.h"
  28. #include "flonum.h"
  29. #include "expr.h"
  30. #include "hash.h"
  31. #include "md.h"
  32. #include "sparc.h"
  33. #include "write.h"
  34. #include "read.h"
  35. #include "symbols.h"
  36.  
  37. void md_begin();
  38. void md_end();
  39. void md_number_to_chars();
  40. void md_assemble();
  41. char *md_atof();
  42. void md_convert_frag();
  43. void md_create_short_jump();
  44. void md_create_long_jump();
  45. int  md_estimate_size_before_relax();
  46. void md_number_to_imm();
  47. void md_number_to_disp();
  48. void md_number_to_field();
  49. void md_ri_to_chars();
  50. void emit_relocations();
  51. static void sparc_ip();
  52.  
  53. const relax_typeS md_relax_table[] = { 0 };
  54.  
  55. /* handle of the OPCODE hash table */
  56. static struct hash_control *op_hash = NULL;
  57.  
  58. static void s_seg(), s_proc(), s_data1(), s_reserve(), s_common();
  59. extern void s_globl(), s_long(), s_short(), s_space(), cons();
  60.  
  61. const pseudo_typeS
  62. md_pseudo_table[] = {
  63.     { "common",     s_common,   0 },
  64.     { "global",     s_globl,    0 },
  65.     { "half",       cons,       2 },
  66.     { "proc",       s_proc,     0 },
  67.     { "reserve",    s_reserve,  0 },
  68.     { "seg",        s_seg,      0 },
  69.     { "skip",       s_space,    0 },
  70.     { "word",       cons,       4 },
  71.     { NULL,         0,          0 },
  72. };
  73.  
  74. int md_short_jump_size = 4;
  75. int md_long_jump_size = 4;
  76. int omagic  =  (0x103 << 16) | OMAGIC;  /* Magic number for header */
  77.  
  78. /* This array holds the chars that always start a comment.  If the
  79.     pre-processor is disabled, these aren't very useful */
  80. char comment_chars[] = "!";    /* JF removed '|' from comment_chars */
  81.  
  82. /* This array holds the chars that only start a comment at the beginning of
  83.    a line.  If the line seems to have the form '# 123 filename'
  84.    .line and .file directives will appear in the pre-processed output */
  85. /* Note that input_file.c hand checks for '#' at the beginning of the
  86.    first line of the input file.  This is because the compiler outputs
  87.    #NO_APP at the beginning of its output. */
  88. /* Also note that '/*' will always start a comment */
  89. char line_comment_chars[] = "#";
  90.  
  91. /* Chars that can be used to separate mant from exp in floating point nums */
  92. char EXP_CHARS[] = "eE";
  93.  
  94. /* Chars that mean this number is a floating point constant */
  95. /* As in 0f12.456 */
  96. /* or    0d1.2345e12 */
  97. char FLT_CHARS[] = "rRsSfFdDxXpP";
  98.  
  99. /* Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be
  100.    changed in read.c .  Ideally it shouldn't have to know about it at all,
  101.    but nothing is ideal around here.
  102.  */
  103. int size_reloc_info = sizeof(struct reloc_info_sparc);
  104.  
  105. static unsigned char octal[256];
  106. #define isoctal(c)  octal[c]
  107. static unsigned char toHex[256];
  108.  
  109. /*
  110.  *  anull bit - causes the branch delay slot instructions to not be executed 
  111.  */
  112. #define ANNUL       (1 << 29)
  113.  
  114. struct sparc_it {
  115.     char    *error;
  116.     unsigned long opcode;
  117.     struct nlist *nlistp;
  118.     expressionS exp;
  119.     int pcrel;
  120.     enum reloc_type reloc;
  121. } the_insn, set_insn;
  122.  
  123. #ifdef __STDC__
  124. #if 0
  125. static void print_insn(struct sparc_it *insn);
  126. #endif
  127. static int getExpression(char *str);
  128. #else
  129. #if 0
  130. static void print_insn();
  131. #endif
  132. static int getExpression();
  133. #endif
  134. static char *expr_end;
  135. static int special_case;
  136.  
  137. #define SPECIAL_CASE_SET    1
  138.  
  139. /*
  140.  * sort of like s_lcomm
  141.  *
  142.  */
  143. static void
  144. s_reserve()
  145. {
  146.     char *name;
  147.     char c;
  148.     char *p;
  149.     int temp;
  150.     symbolS *symbolP;
  151.  
  152.     name = input_line_pointer;
  153.     c = get_symbol_end();
  154.     p = input_line_pointer;
  155.     *p = c;
  156.     SKIP_WHITESPACE();
  157.     if ( * input_line_pointer != ',' ) {
  158.     as_warn("Expected comma after name");
  159.     ignore_rest_of_line();
  160.     return;
  161.     }
  162.     input_line_pointer ++;
  163.     if ((temp = get_absolute_expression()) < 0) {
  164.     as_warn("BSS length (%d.) <0! Ignored.", temp);
  165.     ignore_rest_of_line();
  166.     return;
  167.     }
  168.     *p = 0;
  169.     symbolP = symbol_find_or_make(name);
  170.     *p = c;
  171.     if (strncmp(input_line_pointer, ",\"bss\"", 6) != 0) {
  172.     as_warn("bad .reserve segment: `%s'", input_line_pointer);
  173.     return;
  174.     }
  175.     input_line_pointer += 6;
  176.     if (symbolP->sy_other == 0 
  177.         && symbolP->sy_desc  == 0
  178.     && ((symbolP->sy_type  == N_BSS
  179.     && symbolP->sy_value == local_bss_counter)
  180.     || ((symbolP->sy_type & N_TYPE) == N_UNDF
  181.     && symbolP->sy_value == 0))) {
  182.         symbolP->sy_value = local_bss_counter;
  183.         symbolP->sy_type  = N_BSS;
  184.         symbolP->sy_frag  = & bss_address_frag;
  185.         local_bss_counter += temp;
  186.     } else {
  187.     as_warn( "Ignoring attempt to re-define symbol from %d. to %d.",
  188.         symbolP->sy_value, local_bss_counter );
  189.     }
  190.     demand_empty_rest_of_line();
  191.     return;
  192. }
  193.  
  194. static void
  195. s_common()
  196. {
  197.     register char *name;
  198.     register char c;
  199.     register char *p;
  200.     register int temp;
  201.     register symbolS *    symbolP;
  202.  
  203.     name = input_line_pointer;
  204.     c = get_symbol_end();
  205.     /* just after name is now '\0' */
  206.     p = input_line_pointer;
  207.     *p = c;
  208.     SKIP_WHITESPACE();
  209.     if ( * input_line_pointer != ',' ) {
  210.     as_warn("Expected comma after symbol-name");
  211.     ignore_rest_of_line();
  212.     return;
  213.     }
  214.     input_line_pointer ++; /* skip ',' */
  215.     if ( (temp = get_absolute_expression ()) < 0 ) {
  216.     as_warn(".COMMon length (%d.) <0! Ignored.", temp);
  217.     ignore_rest_of_line();
  218.     return;
  219.     }
  220.     *p = 0;
  221.     symbolP = symbol_find_or_make (name);
  222.     *p = c;
  223.     if (   (symbolP->sy_type & N_TYPE) != N_UNDF ||
  224.         symbolP->sy_other != 0 || symbolP->sy_desc != 0) {
  225.     as_warn( "Ignoring attempt to re-define symbol");
  226.     ignore_rest_of_line();
  227.     return;
  228.     }
  229.     if (symbolP->sy_value) {
  230.     if (symbolP->sy_value != temp) {
  231.         as_warn( "Length of .comm \"%s\" is already %d. Not changed to %d.",
  232.         symbolP->sy_name, symbolP->sy_value, temp);
  233.     }
  234.     } else {
  235.     symbolP->sy_value = temp;
  236.     symbolP->sy_type |= N_EXT;
  237.     }
  238.     know(symbolP->sy_frag == &zero_address_frag);
  239.     if (strncmp(input_line_pointer, ",\"bss\"", 6) != 0) {
  240.     p=input_line_pointer;
  241.     while(*p && *p!='\n')
  242.         p++;
  243.     c= *p;
  244.     *p='\0';
  245.     as_warn("bad .common segment: `%s'", input_line_pointer);
  246.     *p=c;
  247.     return;
  248.     }
  249.     input_line_pointer += 6;
  250.     demand_empty_rest_of_line();
  251.     return;
  252. }
  253.  
  254. static void
  255. s_seg()
  256. {
  257.  
  258.     if (strncmp(input_line_pointer, "\"text\"", 6) == 0) {
  259.     input_line_pointer += 6;
  260.     s_text();
  261.     return;
  262.     }
  263.     if (strncmp(input_line_pointer, "\"data\"", 6) == 0) {
  264.     input_line_pointer += 6;
  265.     s_data();
  266.     return;
  267.     }
  268.     if (strncmp(input_line_pointer, "\"data1\"", 7) == 0) {
  269.     input_line_pointer += 7;
  270.     s_data1();
  271.     return;
  272.     }
  273.     as_warn("Unknown segment type");
  274.     demand_empty_rest_of_line();
  275.     return;
  276. }
  277.  
  278. static void
  279. s_data1()
  280. {
  281.     subseg_new(SEG_DATA, 1);
  282.     demand_empty_rest_of_line();
  283.     return;
  284. }
  285.  
  286. static void
  287. s_proc()
  288. {
  289.     extern char is_end_of_line[];
  290.  
  291.     while (!is_end_of_line[*input_line_pointer]) {
  292.     ++input_line_pointer;
  293.     }
  294.     ++input_line_pointer;
  295.     return;
  296. }
  297.  
  298. /* This function is called once, at assembler startup time.  It should
  299.    set up all the tables, etc. that the MD part of the assembler will need.  */
  300. void
  301. md_begin()
  302. {
  303.   register char *retval = NULL;
  304.   int lose = 0;
  305.   register unsigned int i = 0;
  306.  
  307.   op_hash = hash_new();
  308.   if (op_hash == NULL)
  309.     as_fatal("Virtual memory exhausted");
  310.  
  311.   while (i < NUMOPCODES)
  312.     {
  313.       const char *name = sparc_opcodes[i].name;
  314.       retval = hash_insert(op_hash, name, &sparc_opcodes[i]);
  315.       if(retval != NULL && *retval != '\0')
  316.     {
  317.       fprintf (stderr, "internal error: can't hash `%s': %s\n",
  318.            sparc_opcodes[i].name, retval);
  319.       lose = 1;
  320.     }
  321.       do
  322.     {
  323.       if (sparc_opcodes[i].match & sparc_opcodes[i].lose)
  324.         {
  325.           fprintf (stderr, "internal error: losing opcode: `%s' \"%s\"\n",
  326.                sparc_opcodes[i].name, sparc_opcodes[i].args);
  327.           lose = 1;
  328.         }
  329.       ++i;
  330.     } while (i < NUMOPCODES
  331.          && !strcmp(sparc_opcodes[i].name, name));
  332.     }
  333.  
  334.   if (lose)
  335.     as_fatal ("Broken assembler.  No assembly attempted.");
  336.  
  337.   for (i = '0'; i < '8'; ++i)
  338.     octal[i] = 1;
  339.   for (i = '0'; i <= '9'; ++i)
  340.     toHex[i] = i - '0';
  341.   for (i = 'a'; i <= 'f'; ++i)
  342.     toHex[i] = i + 10 - 'a';
  343.   for (i = 'A'; i <= 'F'; ++i)
  344.     toHex[i] = i + 10 - 'A';
  345. }
  346.  
  347. void
  348. md_end()
  349. {
  350.     return;
  351. }
  352.  
  353. void
  354. md_assemble(str)
  355.     char *str;
  356. {
  357.     char *toP;
  358.     int rsd;
  359.  
  360.     assert(str);
  361.     sparc_ip(str);
  362.     toP = frag_more(4);
  363.     /* put out the opcode */
  364.     md_number_to_chars(toP, the_insn.opcode, 4);
  365.  
  366.     /* put out the symbol-dependent stuff */
  367.     if (the_insn.reloc != NO_RELOC) {
  368.     fix_new(
  369.         frag_now,                           /* which frag */
  370.         (toP - frag_now->fr_literal), /* where */
  371.         4,                                  /* size */
  372.         the_insn.exp.X_add_symbol,
  373.         the_insn.exp.X_subtract_symbol,
  374.         the_insn.exp.X_add_number,
  375.         the_insn.pcrel,
  376.         the_insn.reloc
  377.     );
  378.     }
  379.     switch (special_case) {
  380.  
  381.     case SPECIAL_CASE_SET:
  382.     special_case = 0;
  383.     assert(the_insn.reloc == RELOC_HI22);
  384.     toP = frag_more(4);
  385.     rsd = (the_insn.opcode >> 25) & 0x1f;
  386.     the_insn.opcode = 0x80102000 | (rsd << 25) | (rsd << 14);
  387.     md_number_to_chars(toP, the_insn.opcode, 4);
  388.     fix_new(
  389.         frag_now,                           /* which frag */
  390.         (toP - frag_now->fr_literal),       /* where */
  391.         4,                                  /* size */
  392.         the_insn.exp.X_add_symbol,
  393.         the_insn.exp.X_subtract_symbol,
  394.         the_insn.exp.X_add_number,
  395.         the_insn.pcrel,
  396.         RELOC_LO10
  397.     );
  398.     return;
  399.  
  400.     case 0:
  401.     return;
  402.  
  403.     default:
  404.     abort();
  405.     }
  406. }
  407.  
  408. static void
  409. sparc_ip(str)
  410.     char *str;
  411. {
  412.     char *s;
  413.     const char *args;
  414.     char c;
  415.     unsigned long i;
  416.     struct sparc_opcode *insn;
  417.     char *argsStart;
  418.     unsigned long   opcode;
  419.     unsigned int mask;
  420.     int match = FALSE;
  421.     int comma = 0;
  422.  
  423.     for (s = str; islower(*s) || (*s >= '0' && *s <= '3'); ++s)
  424.     ;
  425.     switch (*s) {
  426.  
  427.     case '\0':
  428.     break;
  429.  
  430.     case ',':
  431.     comma = 1;
  432.  
  433.     /*FALLTHROUGH*/
  434.  
  435.     case ' ':
  436.     *s++ = '\0';
  437.     break;
  438.  
  439.     default:
  440.         as_warn("Unknown opcode: `%s'", str);
  441.         exit(1);
  442.     }
  443.     if ((insn = (struct sparc_opcode *) hash_find(op_hash, str)) == NULL) {
  444.     as_warn("Unknown opcode: `%s'", str);
  445.     return;
  446.     }
  447.     if (comma) {
  448.     *--s = ',';
  449.     }
  450.     argsStart = s;
  451.     for (;;) {
  452.     opcode = insn->match;
  453.     bzero(&the_insn, sizeof(the_insn));
  454.     the_insn.reloc = NO_RELOC;
  455.  
  456.     /*
  457.      * Build the opcode, checking as we go to make
  458.      * sure that the operands match
  459.      */
  460.     for (args = insn->args; ; ++args) {
  461.         switch (*args) {
  462.  
  463.         case '\0':  /* end of args */
  464.         if (*s == '\0') {
  465.             match = TRUE;
  466.         }
  467.         break;
  468.  
  469.         case '+':
  470.         if (*s == '+') {
  471.             ++s;
  472.             continue;
  473.         }
  474.         if (*s == '-') {
  475.             continue;
  476.         }
  477.         break;
  478.  
  479.         case '[':   /* these must match exactly */
  480.         case ']':
  481.         case ',':
  482.         case ' ':
  483.         if (*s++ == *args)
  484.             continue;
  485.         break;
  486.  
  487.         case '#':   /* must be at least one digit */
  488.         if (isdigit(*s++)) {
  489.             while (isdigit(*s)) {
  490.             ++s;
  491.             }
  492.             continue;
  493.         }
  494.         break;
  495.  
  496.         case 'C':   /* coprocessor state register */
  497.         if (strncmp(s, "%csr", 4) == 0) {
  498.             s += 4;
  499.             continue;
  500.         }
  501.         break;
  502.  
  503.         case 'b':    /* next operand is a coprocessor register */
  504.         case 'c':
  505.         case 'D':
  506.             if (*s++ == '%' && *s++ == 'c' && isdigit(*s)) {
  507.             mask = *s++;
  508.             if (isdigit(*s)) {
  509.             mask = 10 * (mask - '0') + (*s++ - '0');
  510.             if (mask >= 32) {
  511.                 break;
  512.             }
  513.             } else {
  514.             mask -= '0';
  515.             }
  516.             switch (*args) {
  517.  
  518.             case 'b':
  519.             opcode |= mask << 14;
  520.             continue;
  521.  
  522.             case 'c':
  523.             opcode |= mask;
  524.             continue;
  525.  
  526.             case 'D':
  527.             opcode |= mask << 25;
  528.             continue;
  529.             }
  530.         }
  531.         break;
  532.  
  533.         case 'r':   /* next operand must be a register */
  534.         case '1':
  535.         case '2':
  536.         case 'd':
  537.         if (*s++ == '%') {
  538.             switch (c = *s++) {
  539.  
  540.             case 'f':   /* frame pointer */
  541.                 if (*s++ == 'p') {
  542.                 mask = 0x1e;
  543.                 break;
  544.             }
  545.             goto error;
  546.  
  547.             case 'g':   /* global register */
  548.             if (isoctal(c = *s++)) {
  549.                 mask = c - '0';
  550.                 break;
  551.             }
  552.             goto error;
  553.  
  554.             case 'i':   /* in register */
  555.             if (isoctal(c = *s++)) {
  556.                 mask = c - '0' + 24;
  557.                 break;
  558.             }
  559.             goto error;
  560.  
  561.             case 'l':   /* local register */
  562.             if (isoctal(c = *s++)) {
  563.                 mask= (c - '0' + 16) ;
  564.                 break;
  565.             }
  566.             goto error;
  567.  
  568.             case 'o':   /* out register */
  569.             if (isoctal(c = *s++)) {
  570.                 mask= (c - '0' + 8) ;
  571.                 break;
  572.             }
  573.             goto error;
  574.  
  575.             case 's':   /* stack pointer */
  576.                 if (*s++ == 'p') {
  577.                 mask= 0xe;
  578.                 break;
  579.             }
  580.             goto error;
  581.  
  582.             case 'r': /* any register */
  583.                 if (!isdigit(c = *s++)) {
  584.                 goto error;
  585.             }
  586.             /* FALLTHROUGH */
  587.             case '0': case '1': case '2': case '3': case '4':
  588.             case '5': case '6': case '7': case '8': case '9':
  589.             if (isdigit(*s)) {
  590.                 if ((c = 10 * (c - '0') + (*s++ - '0')) >= 32) {
  591.                 goto error;
  592.                 }
  593.             } else {
  594.                 c -= '0';
  595.             }
  596.             mask= c;
  597.             break;
  598.  
  599.             default:
  600.             goto error;
  601.             }
  602.             /*
  603.              * Got the register, now figure out where
  604.              * it goes in the opcode.
  605.              */
  606.             switch (*args) {
  607.  
  608.             case '1':
  609.             opcode |= mask << 14;
  610.             continue;
  611.  
  612.             case '2':
  613.             opcode |= mask;
  614.             continue;
  615.  
  616.             case 'd':
  617.             opcode |= mask << 25;
  618.             continue;
  619.  
  620.             case 'r':
  621.             opcode |= (mask << 25) | (mask << 14);
  622.             continue;
  623.             }
  624.         }
  625.         break;
  626.  
  627.         case 'e':    /* next operand is a floating point register */
  628.         case 'f':
  629.         case 'g':
  630.             if (*s++ == '%' && *s++ == 'f' && isdigit(*s)) {
  631.             mask = *s++;
  632.             if (isdigit(*s)) {
  633.             mask = 10 * (mask - '0') + (*s++ - '0');
  634.             if (mask >= 32) {
  635.                 break;
  636.             }
  637.             } else {
  638.             mask -= '0';
  639.             }
  640.             switch (*args) {
  641.  
  642.             case 'e':
  643.             opcode |= mask << 14;
  644.             continue;
  645.  
  646.             case 'f':
  647.             opcode |= mask;
  648.             continue;
  649.  
  650.             case 'g':
  651.             opcode |= mask << 25;
  652.             continue;
  653.             }
  654.         }
  655.         break;
  656.  
  657.         case 'F':
  658.         if (strncmp(s, "%fsr", 4) == 0) {
  659.             s += 4;
  660.             continue;
  661.         }
  662.         break;
  663.  
  664.         case 'h':       /* high 22 bits */
  665.             the_insn.reloc = RELOC_HI22;
  666.         goto immediate;
  667.  
  668.         case 'l':   /* 22 bit PC relative immediate */
  669.             the_insn.reloc = RELOC_WDISP22;
  670.         the_insn.pcrel = 1;
  671.         goto immediate;
  672.  
  673.         case 'L':   /* 30 bit immediate */
  674.             the_insn.reloc = RELOC_WDISP30;
  675.         the_insn.pcrel = 1;
  676.         goto immediate;
  677.  
  678.         case 'i':   /* 13 bit immediate */
  679.             the_insn.reloc = RELOC_BASE13;
  680.  
  681.         /*FALLTHROUGH*/
  682.  
  683.         immediate:
  684.         if(*s==' ')
  685.           s++;
  686.         if (*s == '%') {
  687.             if ((c = s[1]) == 'h' && s[2] == 'i') {
  688.             the_insn.reloc = RELOC_HI22;
  689.             s+=3;
  690.             } else if (c == 'l' && s[2] == 'o') {
  691.             the_insn.reloc = RELOC_LO10;
  692.             s+=3;
  693.             } else
  694.                 break;
  695.         }
  696.         /* Note that if the getExpression() fails, we will still have
  697.            created U entries in the symbol table for the 'symbols'
  698.            in the input string.  Try not to create U symbols for
  699.            registers, etc. */
  700.         {
  701.             /* This stuff checks to see if the expression ends
  702.                in +%reg If it does, it removes the register from
  703.                the expression, and re-sets 's' to point to the
  704.                right place */
  705.  
  706.             char *s1;
  707.  
  708.             for(s1=s;*s1 && *s1!=','&& *s1!=']';s1++)
  709.                 ;
  710.  
  711.             if(s1!=s && isdigit(s1[-1])) {
  712.                 if(s1[-2]=='%' && s1[-3]=='+') {
  713.                     s1-=3;
  714.                     *s1='\0';
  715.                     (void)getExpression(s);
  716.                     *s1='+';
  717.                     s=s1;
  718.                     continue;
  719.                 } else if(index("goli0123456789",s1[-2]) && s1[-3]=='%' && s1[-4]=='+') {
  720.                     s1-=4;
  721.                     *s1='\0';
  722.                     (void)getExpression(s);
  723.                     *s1='+';
  724.                     s=s1;
  725.                     continue;
  726.                 }
  727.             }
  728.         }
  729.         (void)getExpression(s);
  730.         s = expr_end;
  731.         continue;
  732.  
  733.         case 'a':
  734.         if (*s++ == 'a') {
  735.             opcode |= ANNUL;
  736.             continue;
  737.         }
  738.         break;
  739.  
  740.         case 'A':       /* alternate space */
  741.         if (isdigit(*s)) {
  742.             long num;
  743.  
  744.             num=0;
  745.             while (isdigit(*s)) {
  746.             num= num*10 + *s-'0';
  747.             ++s;
  748.             }
  749.             opcode |= num<<5;
  750.             continue;
  751.         }
  752.         break;
  753.         /* abort(); */
  754.  
  755.         case 'p':
  756.         if (strncmp(s, "%psr", 4) == 0) {
  757.             s += 4;
  758.             continue;
  759.         }
  760.         break;
  761.  
  762.         case 'q':   /* floating point queue */
  763.         if (strncmp(s, "%fq", 3) == 0) {
  764.             s += 3;
  765.             continue;
  766.         }
  767.         break;
  768.  
  769.         case 'Q':   /* coprocessor queue */
  770.         if (strncmp(s, "%cq", 3) == 0) {
  771.             s += 3;
  772.             continue;
  773.         }
  774.         break;
  775.  
  776.         case 'S':
  777.         if (strcmp(str, "set") == 0) {
  778.             special_case = SPECIAL_CASE_SET;
  779.             continue;
  780.         }
  781.         break;
  782.  
  783.         case 't':
  784.         if (strncmp(s, "%tbr", 4) != 0)
  785.             break;
  786.         s += 4;
  787.         continue;
  788.  
  789.         case 'w':
  790.         if (strncmp(s, "%wim", 4) != 0)
  791.             break;
  792.         s += 4;
  793.         continue;
  794.  
  795.         case 'y':
  796.         if (strncmp(s, "%y", 2) != 0)
  797.             break;
  798.         s += 2;
  799.         continue;
  800.  
  801.         default:
  802.         abort();
  803.         }
  804.         break;
  805.     }
  806.     error:
  807.     if (match == FALSE)
  808.       {
  809.         /* Args don't match.  */
  810.         if (&insn[1] - sparc_opcodes < NUMOPCODES
  811.         && !strcmp(insn->name, insn[1].name))
  812.           {
  813.         ++insn;
  814.         s = argsStart;
  815.         continue;
  816.           }
  817.         else
  818.           {
  819.         as_warn("Illegal operands");
  820.         return;
  821.           }
  822.       }
  823.     break;
  824.     }
  825.  
  826.     the_insn.opcode = opcode;
  827.     return;
  828. }
  829.  
  830. static int
  831. getExpression(str)
  832.     char *str;
  833. {
  834.     char *save_in;
  835.     segT seg;
  836.  
  837.     save_in = input_line_pointer;
  838.     input_line_pointer = str;
  839.     switch (seg = expression(&the_insn.exp)) {
  840.  
  841.     case SEG_ABSOLUTE:
  842.     case SEG_TEXT:
  843.     case SEG_DATA:
  844.     case SEG_BSS:
  845.     case SEG_UNKNOWN:
  846.     case SEG_DIFFERENCE:
  847.     case SEG_BIG:
  848.     case SEG_NONE:
  849.     break;
  850.  
  851.     default:
  852.     the_insn.error = "bad segment";
  853.     expr_end = input_line_pointer;
  854.     input_line_pointer=save_in;
  855.     return 1;
  856.     }
  857.     expr_end = input_line_pointer;
  858.     input_line_pointer = save_in;
  859.     return 0;
  860. }
  861.  
  862.  
  863. /*
  864.     This is identical to the md_atof in m68k.c.  I think this is right,
  865.     but I'm not sure.
  866.  
  867.    Turn a string in input_line_pointer into a floating point constant of type
  868.    type, and store the appropriate bytes in *litP.  The number of LITTLENUMS
  869.    emitted is stored in *sizeP .  An error message is returned, or NULL on OK.
  870.  */
  871.  
  872. /* Equal to MAX_PRECISION in atof-ieee.c */
  873. #define MAX_LITTLENUMS 6
  874.  
  875. char *
  876. md_atof(type,litP,sizeP)
  877.     char type;
  878.     char *litP;
  879.     int *sizeP;
  880. {
  881.     int    prec;
  882.     LITTLENUM_TYPE words[MAX_LITTLENUMS];
  883.     LITTLENUM_TYPE *wordP;
  884.     char    *t;
  885.     char    *atof_ieee();
  886.  
  887.     switch(type) {
  888.  
  889.     case 'f':
  890.     case 'F':
  891.     case 's':
  892.     case 'S':
  893.     prec = 2;
  894.     break;
  895.  
  896.     case 'd':
  897.     case 'D':
  898.     case 'r':
  899.     case 'R':
  900.     prec = 4;
  901.     break;
  902.  
  903.     case 'x':
  904.     case 'X':
  905.     prec = 6;
  906.     break;
  907.  
  908.     case 'p':
  909.     case 'P':
  910.     prec = 6;
  911.     break;
  912.  
  913.     default:
  914.     *sizeP=0;
  915.     return "Bad call to MD_ATOF()";
  916.     }
  917.     t=atof_ieee(input_line_pointer,type,words);
  918.     if(t)
  919.     input_line_pointer=t;
  920.     *sizeP=prec * sizeof(LITTLENUM_TYPE);
  921.     for(wordP=words;prec--;) {
  922.     md_number_to_chars(litP,(long)(*wordP++),sizeof(LITTLENUM_TYPE));
  923.     litP+=sizeof(LITTLENUM_TYPE);
  924.     }
  925.     return "";    /* Someone should teach Dean about null pointers */
  926. }
  927.  
  928. /*
  929.  * Write out big-endian.
  930.  */
  931. void
  932. md_number_to_chars(buf,val,n)
  933.     char *buf;
  934.     long val;
  935.     int n;
  936. {
  937.  
  938.     switch(n) {
  939.  
  940.     case 4:
  941.     *buf++ = val >> 24;
  942.     *buf++ = val >> 16;
  943.     case 2:
  944.     *buf++ = val >> 8;
  945.     case 1:
  946.     *buf = val;
  947.     break;
  948.  
  949.     default:
  950.     abort();
  951.     }
  952.     return;
  953. }
  954.  
  955. void
  956. md_number_to_imm(buf,val,n, fixP, seg_type)
  957.     char *buf;
  958.     long val;
  959.     int n;
  960.     fixS *fixP;
  961.     int seg_type;
  962. {
  963.     /* if (seg_type != N_TEXT || fixP->fx_r_type == NO_RELOC) { */
  964.     if (  (seg_type != N_TEXT && fixP->fx_r_type > RELOC_DISP32 )
  965.       || fixP->fx_r_type == NO_RELOC) {
  966.       /* should never get here for current relocs ... */
  967.  
  968.     switch (n) {
  969.     case 1:
  970.         *buf = val;
  971.         break;
  972.     case 2:
  973.         *buf++ = (val>>8);
  974.         *buf = val;
  975.         break;
  976.     case 4:
  977.         *buf++ = (val>>24);
  978.         *buf++ = (val>>16);
  979.         *buf++ = (val>>8);
  980.         *buf = val;
  981.         break;
  982.     default:
  983.         abort();
  984.     }
  985.     return;
  986.     }
  987.  
  988.     assert(n == 4);
  989.     assert(fixP->fx_r_type < NO_RELOC);
  990.  
  991.     /*
  992.      * This is a hack.  There should be a better way to
  993.      * handle this.
  994.      */
  995.     if (fixP->fx_r_type == RELOC_WDISP30 && fixP->fx_addsy) {
  996.         val += fixP->fx_where + fixP->fx_frag->fr_address;
  997.     }
  998.  
  999.     switch (fixP->fx_r_type) {
  1000.  
  1001.     case RELOC_32:
  1002.     buf[0] = 0; /* val >> 24; */
  1003.     buf[1] = 0; /* val >> 16; */
  1004.     buf[2] = 0; /* val >> 8; */
  1005.     buf[3] = 0; /* val; */
  1006.     break;
  1007.  
  1008. #if 0
  1009.     case RELOC_8:         /* These don't seem to ever be needed. */
  1010.     case RELOC_16:
  1011.     case RELOC_DISP8:
  1012.     case RELOC_DISP16:
  1013.     case RELOC_DISP32:
  1014. #endif
  1015.     case RELOC_WDISP30:
  1016.     val = (val >>= 2) + 1;
  1017.     buf[0] |= (val >> 24) & 0x3f;
  1018.     buf[1]= (val >> 16);
  1019.     buf[2] = val >> 8;
  1020.     buf[3] = val;
  1021.     break;
  1022.  
  1023.     case RELOC_HI22:
  1024.     if(!fixP->fx_addsy) {
  1025.       buf[1] |= (val >> 26) & 0x3f;
  1026.       buf[2] = val >> 18;
  1027.       buf[3] = val >> 10;
  1028.     } else {
  1029.       buf[2]=0;
  1030.       buf[3]=0;
  1031.     }
  1032.     break;
  1033. #if 0
  1034.     case RELOC_22:
  1035.     case RELOC_13:
  1036. #endif
  1037.     case RELOC_LO10:
  1038.     if(!fixP->fx_addsy) {
  1039.       buf[2] |= (val >> 8) & 0x03;
  1040.       buf[3] = val;
  1041.     } else
  1042.       buf[3]=0;
  1043.     break;
  1044. #if 0
  1045.     case RELOC_SFA_BASE:
  1046.     case RELOC_SFA_OFF13:
  1047.     case RELOC_BASE10:
  1048. #endif
  1049.     case RELOC_BASE13:
  1050.     buf[2] |= (val >> 8) & 0x1f;
  1051.     buf[3] = val;
  1052.     break;
  1053.  
  1054.     case RELOC_WDISP22:
  1055.     val = (val >>= 2) + 1;
  1056.     /* FALLTHROUGH */
  1057.     case RELOC_BASE22:
  1058.     buf[1] |= (val >> 16) & 0x3f;
  1059.     buf[2] = val >> 8;
  1060.     buf[3] = val;
  1061.     break;
  1062.  
  1063. #if 0
  1064.     case RELOC_PC10: 
  1065.     case RELOC_PC22: 
  1066.     case RELOC_JMP_TBL:
  1067.     case RELOC_SEGOFF16:
  1068.     case RELOC_GLOB_DAT:
  1069.     case RELOC_JMP_SLOT: 
  1070.     case RELOC_RELATIVE:
  1071. #endif
  1072.  
  1073.     case NO_RELOC:
  1074.     default:
  1075.     as_warn("bad relocation type: 0x%02x", fixP->fx_r_type);
  1076.     break;
  1077.     }
  1078.     return;
  1079. }
  1080.  
  1081. /* should never be called for sparc */
  1082. void
  1083. md_create_short_jump(ptr, from_addr, to_addr, frag, to_symbol)
  1084.     char *ptr;
  1085.     long from_addr, to_addr;
  1086. {
  1087.     fprintf(stderr, "sparc_create_short_jmp\n");
  1088.     abort();
  1089. }
  1090.  
  1091. /* should never be called for sparc */
  1092. void
  1093. md_number_to_disp(buf,val,n)
  1094.     char    *buf;
  1095.     long    val;
  1096. {
  1097.     fprintf(stderr, "md_number_to_disp\n");
  1098.     abort();
  1099. }
  1100.  
  1101. /* should never be called for sparc */
  1102. void
  1103. md_number_to_field(buf,val,fix)
  1104.     char *buf;
  1105.     long val;
  1106.     void *fix;
  1107. {
  1108.     fprintf(stderr, "sparc_number_to_field\n");
  1109.     abort();
  1110. }
  1111.  
  1112. /* the bit-field entries in the relocation_info struct plays hell 
  1113.    with the byte-order problems of cross-assembly.  So as a hack,
  1114.    I added this mach. dependent ri twiddler.  Ugly, but it gets
  1115.    you there. -KWK */
  1116. /* on sparc: first 4 bytes are normal unsigned long address, next three
  1117.    bytes are index, most sig. byte first.  Byte 7 is broken up with
  1118.    bit 7 as external, bits 6 & 5 unused, and the lower
  1119.    five bits as relocation type.  Next 4 bytes are long int addend. */
  1120. /* Thanx and a tip of the hat to Michael Bloom, mb@ttidca.tti.com */
  1121. void
  1122. md_ri_to_chars(ri_p, ri)
  1123.      struct reloc_info_sparc *ri_p, ri;
  1124. {
  1125.   unsigned char the_bytes[sizeof(*ri_p)];
  1126.   
  1127.   /* this is easy */
  1128.   md_number_to_chars(the_bytes, ri.r_address, sizeof(ri.r_address));
  1129.   /* now the fun stuff */
  1130.   the_bytes[4] = (ri.r_index >> 16) & 0x0ff;
  1131.   the_bytes[5] = (ri.r_index >> 8) & 0x0ff;
  1132.   the_bytes[6] = ri.r_index & 0x0ff;
  1133.   the_bytes[7] = ((ri.r_extern << 7)  & 0x80) | (0 & 0x60) | (ri.r_type & 0x1F);
  1134.   /* Also easy */
  1135.   md_number_to_chars(&the_bytes[8], ri.r_addend, sizeof(ri.r_addend));
  1136.   /* now put it back where you found it, Junior... */
  1137.   bcopy (the_bytes, (char *)ri_p, sizeof(*ri_p));
  1138. }
  1139.  
  1140. /* should never be called for sparc */
  1141. void
  1142. md_convert_frag(fragP)
  1143.     register fragS *fragP;
  1144. {
  1145.     fprintf(stderr, "sparc_convert_frag\n");
  1146.     abort();
  1147. }
  1148.  
  1149. /* should never be called for sparc */
  1150. void
  1151. md_create_long_jump(ptr, from_addr, to_addr, frag, to_symbol)
  1152.     char    *ptr;
  1153.     long    from_addr,
  1154.             to_addr;
  1155.     fragS    *frag;
  1156.     symbolS    *to_symbol;
  1157. {
  1158.     fprintf(stderr, "sparc_create_long_jump\n");
  1159.     abort();
  1160. }
  1161.  
  1162. /* should never be called for sparc */
  1163. int
  1164. md_estimate_size_before_relax(fragP, segtype)
  1165.     register fragS *fragP;
  1166. {
  1167.     fprintf(stderr, "sparc_estimate_size_before_relax\n");
  1168.     abort();
  1169.     return 0;
  1170. }
  1171.  
  1172. #if 0
  1173. /* for debugging only */
  1174. static void
  1175. print_insn(insn)
  1176.     struct sparc_it *insn;
  1177. {
  1178.     char *Reloc[] = {
  1179.     "RELOC_8",
  1180.     "RELOC_16",
  1181.     "RELOC_32",
  1182.     "RELOC_DISP8",
  1183.     "RELOC_DISP16",
  1184.     "RELOC_DISP32",
  1185.     "RELOC_WDISP30",
  1186.     "RELOC_WDISP22",
  1187.     "RELOC_HI22",
  1188.     "RELOC_22",
  1189.     "RELOC_13",
  1190.     "RELOC_LO10",
  1191.     "RELOC_SFA_BASE",
  1192.     "RELOC_SFA_OFF13",
  1193.     "RELOC_BASE10",
  1194.     "RELOC_BASE13",
  1195.     "RELOC_BASE22",
  1196.     "RELOC_PC10",
  1197.     "RELOC_PC22",
  1198.     "RELOC_JMP_TBL",
  1199.     "RELOC_SEGOFF16",
  1200.     "RELOC_GLOB_DAT",
  1201.     "RELOC_JMP_SLOT",
  1202.     "RELOC_RELATIVE",
  1203.     "NO_RELOC"
  1204.     };
  1205.  
  1206.     if (insn->error) {
  1207.     fprintf(stderr, "ERROR: %s\n");
  1208.     }
  1209.     fprintf(stderr, "opcode=0x%08x\n", insn->opcode);
  1210.     fprintf(stderr, "reloc = %s\n", Reloc[insn->reloc]);
  1211.     fprintf(stderr, "exp =  {\n");
  1212.     fprintf(stderr, "\t\tX_add_symbol = %s\n",
  1213.     insn->exp.X_add_symbol ?
  1214.     (insn->exp.X_add_symbol->sy_name ? 
  1215.     insn->exp.X_add_symbol->sy_name : "???") : "0");
  1216.     fprintf(stderr, "\t\tX_sub_symbol = %s\n",
  1217.     insn->exp.X_subtract_symbol ?
  1218.         (insn->exp.X_subtract_symbol->sy_name ? 
  1219.             insn->exp.X_subtract_symbol->sy_name : "???") : "0");
  1220.     fprintf(stderr, "\t\tX_add_number = %d\n",
  1221.     insn->exp.X_add_number);
  1222.     fprintf(stderr, "}\n");
  1223.     return;
  1224. }
  1225. #endif
  1226.  
  1227. /*
  1228.  * Sparc relocations are completely different, so it needs
  1229.  * this machine dependent routine to emit them.
  1230.  */
  1231. void
  1232. emit_relocations(fixP, segment_address_in_file)
  1233.     register fixS *fixP;
  1234.     relax_addressT segment_address_in_file;
  1235. {
  1236.     struct reloc_info_sparc ri;
  1237.     register symbolS *symbolP;
  1238.     extern char *next_object_file_charP;
  1239.     long add_number;
  1240.  
  1241.     bzero((char *) &ri, sizeof(ri));
  1242.     for (; fixP; fixP = fixP->fx_next) {
  1243.  
  1244.     if (fixP->fx_r_type >= NO_RELOC) {
  1245.         fprintf(stderr, "fixP->fx_r_type = %d\n", fixP->fx_r_type);
  1246.         abort();
  1247.     }
  1248.  
  1249.     if ((symbolP = fixP->fx_addsy) != NULL) {
  1250.         ri.r_address = fixP->fx_frag->fr_address +
  1251.             fixP->fx_where - segment_address_in_file;
  1252.         if ((symbolP->sy_type & N_TYPE) == N_UNDF) {
  1253.         ri.r_extern = 1;
  1254.         ri.r_index = symbolP->sy_number;
  1255.         } else {
  1256.         ri.r_extern = 0;
  1257.         ri.r_index = symbolP->sy_type & N_TYPE;
  1258.         }
  1259.         if (symbolP && symbolP->sy_frag) {
  1260.         ri.r_addend = symbolP->sy_frag->fr_address;
  1261.         }
  1262.         ri.r_type = fixP->fx_r_type;
  1263.         if (fixP->fx_pcrel) {
  1264. /*        ri.r_addend -= fixP->fx_where;          */
  1265.         ri.r_addend -= ri.r_address;            
  1266.         } else {
  1267.         ri.r_addend = fixP->fx_addnumber;
  1268.         }
  1269.  
  1270. /*        md_ri_to_chars((char *) &ri, ri);        */
  1271.         append(&next_object_file_charP, (char *)& ri, sizeof(ri));
  1272.     }
  1273.     }
  1274.     return;
  1275. }
  1276.  
  1277. int
  1278. md_parse_option(argP,cntP,vecP)
  1279.     char **argP;
  1280.     int *cntP;
  1281.     char ***vecP;
  1282. {
  1283.     return 1;
  1284. }
  1285.  
  1286.